package ru.jkff.jalgebra.monoid;

import ru.jkff.jalgebra.order.BoundedLattice;
import ru.jkff.jalgebra.order.Lattices;

/**
 * User: jkff
 * Date: Aug 22, 2009
 * Time: 1:03:32 PM
 */
public abstract class Monoids {
    public static Monoid<Integer> INT_SUM = new Monoid<Integer>() {
        public Integer unit()                        { return 0;     }
        public Integer combine(Integer a, Integer b) { return a + b; }
    };
    public static Monoid<Double> DOUBLE_SUM = new Monoid<Double>() {
        public Double unit()                      { return 0.0;   }
        public Double combine(Double a, Double b) { return a + b; }
    };

    public static Monoid<Boolean> ALL = infInLattice(Lattices.BOOLEAN_AND_OR);
    public static Monoid<Boolean> ANY = supInLattice(Lattices.BOOLEAN_AND_OR);

    public static <T> Monoid<T> infInLattice(final BoundedLattice<T> lat) {
        return new Monoid<T>() {
            public T unit()            { return lat.max();     }
            public T combine(T a, T b) { return lat.inf(a, b); }
        };
    }
    public static <T> Monoid<T> supInLattice(final BoundedLattice<T> lat) {
        return infInLattice(lat.flip());
    }
}
